package com.mcodesal.framework;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

/**
 * This is an OpenGL solution for drawing 2D sprites.  It uses a textured
 * primitive plane.
 * 
 * NOTES:  
 * Utilizes CCW winding and back face culling is ON.  If you don't see anything,
 * you're probably looking at a back face.
 * 
 * Origin is at the bottom left.
 * 
 * @author Matias
 *
 */
public class Sprite2D {
	// Our vertices.
	public int x = 0;
	public int y = 0;
	public int height = 1;
	public int width = 1;
	private int mTextureID;
	private float vertices[] = {
				0f,  0f, 0f,  // 0, Bottom Left
				0, 1f, 0f,  // 1, Top Left
				1f, 0f, 0f,  // 2, Bottom Right
				1f,  1f, 0f,  // 3, Top Right
	};
	
	private float texture[] = {
	        // Mapping coordinates for the vertices
	        0.0f, 0.0f,     // bottom left     (V2)
	        0.0f, 1.0f,     // top left  (V1)
	        1.0f, 0.0f,     // bottom right    (V4)
	        1.0f, 1.0f      // top right (V3)
	};

	// Our vertex buffer.
	private FloatBuffer vertexBuffer;
	
	private FloatBuffer textureBuffer;  // buffer holding the texture coordinates
	
	/**
	 * Constructor for defining variable dimension
	 * @param w -- width
	 * @param h -- height
	 */
	public Sprite2D(int w, int h) {
		height = h;
		width = w;
		vertices[4] = h;
		vertices[10] = h;
		vertices[6] = w;
		vertices[9] = w;
		// a float is 4 bytes, therefore we multiply the number if
		// vertices with 4.
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		vertexBuffer = byteBuffer.asFloatBuffer();
		vertexBuffer.put(vertices);
		vertexBuffer.position(0);
		
		
		byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		textureBuffer = byteBuffer.asFloatBuffer();
		textureBuffer.put(texture);
		textureBuffer.position(0);
		

	}
	public void setTexture(int textureID) {
		mTextureID = textureID;
	}
	public void setFrameClip(float x1, float y1, float x2, float y2) {
		texture[0] = x1;
		texture[1] = y1;
		texture[2] = x1;
		texture[3] = y2;
		texture[4] = x2;
		texture[5] = y1;
		texture[6] = x2;
		texture[7] = y2;
		
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
		byteBuffer.order(ByteOrder.nativeOrder());
		textureBuffer = byteBuffer.asFloatBuffer();
		textureBuffer.put(texture);
		textureBuffer.position(0);
	}

	/**
	 * This function draws our square on screen.
	 * @param gl
	 * @param textureID -- integer value representing texture index
	 */
	public void draw(GL10 gl) {
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
		// Counter-clockwise winding.
		gl.glFrontFace(GL10.GL_CCW); // OpenGL docs
		// Enable face culling.
		gl.glEnable(GL10.GL_CULL_FACE); // OpenGL docs
		// What faces to remove with the face culling.
		// Enabled the vertices buffer for writing and to be used during
		// rendering.
		gl.glCullFace(GL10.GL_BACK);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// OpenGL docs.
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		// Specifies the location and data format of an array of vertex
		// coordinates to use when rendering.
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, // OpenGL docs
                                 vertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
		
		// Disable the buffers.
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL docs
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
		// Disable face culling.
		gl.glDisable(GL10.GL_CULL_FACE); // OpenGL docs
		
	}
}
